<?php
namespace app\home\controller\user;

use app\BaseController;


use app\common\model\MoneyLog;
use app\common\model\PayWithdraw;
use app\common\model\PayRecharge;
use app\common\model\SysConfig;
use app\common\model\PayChannel;
use app\common\model\User as models;
use app\common\traites\PublicCrudTrait;

use think\exception\ValidateException;
use think\facade\Db;
use hg\apidoc\annotation as Apidoc;

/**
 *
 * @Apidoc\Title("个人中心")
 * */
class Money extends BaseController
{
    protected $model;
    use PublicCrudTrait;

    public function initialize()
    {
        $this->model = new models();
        parent::initialize(); // TODO: Change the autogenerated stub
    }

    /**
     * @Apidoc\Title("提现操作")
     * @Apidoc\Method("POST")
     * @Apidoc\Param("money_type", type="string",require=true, desc="金额类型")
     * @Apidoc\Param("money", type="string",require=true, desc="充值金额")
     * @Apidoc\Param("sys_bank_id", type="string",require=true, desc="充值通道ID")
     * @Apidoc\Param("u_bank_name", type="string",require=true, desc="进行充值的银行名称")
     * @Apidoc\Param("u_bank_user_name", type="string",require=true, desc="进行充值的银行用户姓名")
     * @Apidoc\Param("u_bank_card", type="string",require=true, desc="进行充值的银行卡卡号")
     * @Apidoc\Param("withdraw_pwd", type="string",require=true, desc="提现密码")
     * @Apidoc\Returned("data", type="bool", desc="返回成功失败结果")
     */
    public function withdraw() {
        $uid = session('home_user.id');
        //过滤数据
        $postField = 'money,withdraw_pwd,money_type';
        $params = $this->request->only(explode(',', $postField), 'post', null);      

        try {
            $this->validate($params,
                [
                    'money_type' => 'require', //
                    'money' => 'require|float|max:20', //
                    'withdraw_pwd' => 'require|max:200', //
                ], [
                    'money_type' => 'Please pass the correct withdraw type',
                    'money' => 'Please fill in the correct withdraw amount',
                    'withdraw_pwd' => 'Please fill in the correct withdraw password',
                ]
            );
        } catch (ValidateException $e) {
            // 验证失败 输出错误信息
            return show([], config('ToConfig.http_code.error'), $e->getError());
        }

        $type = $params['money_type'];
        // 禁止提现类型
        if (in_array($type, ['money_juanzeng', 'money_cishan'])) {
            return show([], config('ToConfig.http_code.error'), '禁止提现');
        }

        // 传递参数限制
        if (!in_array($type, ['money_balance', 'money_gongfu', 'money_zhifu', 'money_cishan', 'money_juanzeng'])) {
            return show([], config('ToConfig.http_code.error'), '参数错误');
        }
        // 获取最新用户模型
        $user = $this->model->where('id', $uid)->find();
        // 提现密码 检查
        if (pwdEncryption($params['withdraw_pwd']) != $user['withdraw_pwd']) {
            return show([], config('ToConfig.http_code.error'), '支付密码错误');
        }
        //检查银行卡 如果没有 银行卡 没法提现
        $UserBank = new UserBank();
        $res_Bank = $UserBank->where('user_id', $uid)->find();
        if (!$res_Bank) {
            return show([], config('ToConfig.http_code.error'), '暂未添加银行卡，无法提现');
        }

        // 每天提现次数限制
        $PayWithdraw = new PayWithdraw();
        $SysConfig = new SysConfig();
        $withdraw_day_count = $PayWithdraw->where('uid', $uid)->where('status', 'in', '0,1')
            ->where('create_time', '>', date('Y-m-d'))->count('id');
        $withdraw_day_number = $SysConfig->where('name', 'withdraw_day_number')->value('value');
        if ($withdraw_day_count >= $withdraw_day_number) {
            return show([], config('ToConfig.http_code.error'), '今日提现次数已达限制');
        }

        if ($type == 'money_balance') {
            // 最低提现额度
            $min_ben_withdraw = $SysConfig->where('name', 'min_money_withdraw')->value('value');

            // 最小提现金额检查
            if ($min_ben_withdraw > $params['money']) {
                return show([], config('ToConfig.http_code.error'), '最小提现金额：' . $min_ben_withdraw);
            }

            // 检测购买数据
            // $buy_zhifu_nums = $this->getBuyProductZhiFuNums($uid);
            $map = [];
            $map['user_id'] = $uid;
            // $map['class_type_id'] = 3;
            $buy_zhifu_nums = (new TouziProductOrder())->where('class_type_id','in','2,3')->where($map)->count();

            if($buy_zhifu_nums <= 0){
                return show([], config('ToConfig.http_code.error'), '请参与共富事业后再进行提现');
            }

        }
        if($type == 'money_zhifu'){
        }
        if ($type == 'money_gongfu') {
        }

        // 提现时间限制
        $withdraw_time = $SysConfig->where('name', 'withdraw_time')->value('value');
        $withdraw_time_arr = explode('#', $withdraw_time);
        $str_time_start = date('Y-m-d') . ' ' . $withdraw_time_arr[0] . ':00';
        $str_time_end = date('Y-m-d') . ' ' . $withdraw_time_arr[1] . ':00';
        $time_start = strtotime($str_time_start);
        $time_end = strtotime($str_time_end);
        if (time() < $time_start || time() > $time_end) {
            return show([], config('ToConfig.http_code.error'), '提现时间不在范围');
        }
        // 手续费
        $fee = 0;
        
        // 用户 余额检查
        if ($params['money'] > $user[$type]) {
            return show([], config('ToConfig.http_code.error'), '余额不足');
        }

        // 执行提现动作
        Db::startTrans();
        try {
            //写入提现记录
            $data['create_time'] = date('Y-m-d H:i:s');
            $data['before_balance'] = $user[$type];
            $data['after_balance'] = $user[$type] - $params['money'];
            $data['money'] = $params['money'];
            $data['money_type'] = $type;
            $data['u_bank_name'] = $res_Bank['bank_name'] . $res_Bank['bank_address'];
            $data['u_bank_user_name'] = $res_Bank['true_name'];
            $data['u_bank_card'] = $res_Bank['card_number'];
            $data['money_fee'] = round($fee * $params['money'], 2);
            $data['money_actual'] = $params['money'] - round($fee * $params['money'], 2);
            $data['order_on'] = orderCode('TX');
            $data['uid'] = $uid;
            //  $data['img']=$params['img'];
            $data['u_ip'] = $this->request->ip();
            // 插入数据库 
            $order_id = $PayWithdraw->insertGetId($data);
            //提现 占用 提现金额
            User::decreaseBy($type, $uid, $params['money']);
            MoneyLog::flowing(2, 2, 1, 201, $user, $params['money'], $order_id, '用户提现[' . money_type_name($type) . '],手续费率:' . $fee, $type);
            Db::commit();
            return show();
        } catch (\Exception $e) {
            Db::rollback();
            // 验证失败 输出错误信息
            return show([], config('ToConfig.http_code.error'), $e->getError());
        }
    }
    /**
     * @Apidoc\Title("提现列表")
     * @Apidoc\Method("POST")
     * @Apidoc\Returned("data", type="bool", desc="返回成功失败结果")
     */
    public function withdraw_records(){
        $uid= session('home_user.id');
        //当前页
        $page = $this->request->post('page', 1);
        //每页显示数量
        $limit = $this->request->post('limit', 10);
        //查询搜索条件
        $post = array_filter($this->request->post());
        $where=array();
        $where[]=array('uid','=',$uid);
        $PayWithdraw=new PayWithdraw();

        $res=$PayWithdraw->where($where)
            ->order('create_time desc')
            ->paginate(['list_rows' => $limit, 'page' => $page], false)
            ->each(function($item, $key){
                // $status_text = ['申请中','已经完成','已拒绝','国家财政部门审核到账时间20天'];
                $status_text = ['申请中','已经完成','已拒绝','缴纳管理费可立即到账，联系客服核实出款信息'];
                $item->status_text ='未知';
                $item->status_text = $status_text[$item['status']];

                // 特殊说明
                if($item['money_type']=='money_gongfu' && $item['status'] == 0){
                    $item->status_text ='正在打款，最迟10个工作日以内到账';
                }

                if($item['money_type']=='money_zhifu' && $item['status'] == 0){
                    $item->status_text ='审核5-15个工作日内完成到账';
                }

                // 更新
                if($item['status']==2){
                    $item->status_text .= ': '.$item->msg;
                }
            });
        return show($res);
    }

    /**
     * @Apidoc\Title("充值操作")
     * @Apidoc\Method("POST")
     * @Apidoc\Param("money", type="string",require=true, desc="充值金额")
     * @Apidoc\Param("sys_bank_id", type="string",require=true, desc="充值通道ID")
     * @Apidoc\Param("u_bank_name", type="string",require=true, desc="进行充值的银行名称")
     * @Apidoc\Param("u_bank_user_name", type="string",require=true, desc="进行充值的银行用户姓名")
     * @Apidoc\Param("u_bank_card", type="string",require=true, desc="进行充值的银行卡卡号")
     * @Apidoc\Returned("data", type="bool", desc="返回成功失败结果")
     */
    public function recharge() {
        $uid = session('home_user.id');
        //过滤数据
        //$postField = 'money,sys_bank_id,u_bank_name,u_bank_user_name,u_bank_card,img';
        $postField = 'money,sys_bank_id';
        $params = $this->request->only(explode(',', $postField), 'post', null);
        try {
            $this->validate($params,
                [
                    //'type' => 'require|number|in:1,2', //
                    'money'       => 'require|float|max:20', //
                    'sys_bank_id' => 'require|max:5', //
                    // 'u_bank_name' => 'max:200', //
                    // 'u_bank_user_name' => 'max:200', //
                    // 'u_bank_card' => 'max:200', //
                    // 'img' => 'max:200', //
                ], [
                    //'type' => 'Please pass the correct recharge type',
                    'money'       => 'Please fill in the correct recharge amount',
                    'sys_bank_id' => 'Please fill in the correct recharge collection parameters',
                    // 'u_bank_name' => 'Please fill in the correct name of the paying bank',
                    // 'u_bank_user_name' => 'Please fill in the correct payment username',
                    // 'u_bank_card' => 'Please fill in the correct recharge parameters',
                    //  'img' => '请上传正确的充值截图',
                ]
            );
        } catch (ValidateException $e) {
            // 验证失败 输出错误信息
            return show([], config('ToConfig.http_code.error'), $e->getError());
        }
        if((int)$params['money'] <5){
            return show([], config('ToConfig.http_code.error'), '充值金额最低500元');
        }
        // 获取当前用户信息
        $user = $this->model->where('id', $uid)->find();
        // 获取配置信息
        //$SysConfig          = new SysConfig();
        //$min_ben_recharge   = $SysConfig->where('name', 'min_ben_recharge')->value('value');
        //$recharge_day_times = $SysConfig->where('name', 'recharge_day_times')->value('value');
        // 限制最小充值金额
        /*if ($min_ben_recharge > $params['money']) {
            return show([], config('ToConfig.http_code.error'), 'minimum recharge is ' . $min_ben_recharge);
        }*/
        $PayRecharge = new PayRecharge();
        // 限制当天充值频率
        /*$count = $PayRecharge->where(['uid' => $uid, 'status' => 0])->where('create_time', '>', date('Y-m-d'))->count();
        if ($count > $recharge_day_times) {
            return show([], config('ToConfig.http_code.error'), 'Your operation is too frequent, please try again later');
        }*/
        $tong = PayChannel::find($params['sys_bank_id']);
        [$channel, $channel_id] = explode('-', $tong->channel_id);

        //写入充值记录
        $data['before_balance'] = $user['money_balance'];
        $data['create_time'] = date('Y-m-d H:i:s');
        $data['money']       = $params['money'];
        $data['sys_bank_id'] = $params['sys_bank_id'];
        $data['money_type']  = 'money_balance';
        $data['pay_type']    = $tong->channel_id;
        // $data['u_bank_name']=$params['u_bank_name'];
        // $data['u_bank_user_name']=$params['u_bank_user_name'];
        // $data['u_bank_card']=$params['u_bank_card'];
        $data['order_on'] = orderCode('CZ');
        $data['uid']      = $uid;
        //$data['img']=$params['img']; // 暂时不支持 上传图片
        $data['u_ip'] = $this->request->ip();
        $res = $PayRecharge->insert($data);
        if ($res) {
            $pay_data = (new Pay())->pay($channel,$channel_id, $data['order_on'], $data['money']);
            return show($pay_data);
        } else {
            return show([], config('ToConfig.http_code.error'), 'Recharging failed, please try again later');
        }
    }

    /**
     * @Apidoc\Title("充值列表")
     * @Apidoc\Method("POST")
     * @Apidoc\Returned("data", type="bool", desc="返回成功失败结果")
     */
    public function recharge_records(){
        $uid= session('home_user.id');
        //当前页
        $page = $this->request->post('page', 1);
        //每页显示数量
        $limit = $this->request->post('limit', 10);
        //查询搜索条件
        $post = array_filter($this->request->post());
        $where[]=array('uid','=',$uid);
        // if (isset($post['start']) && isset($post['end'])) {
        //     $where[]=array('create_time','>=',$post['start']);
        //     $where[]=array('create_time','<',$post['end']);
        // }
        $PayRecharge=new PayRecharge();
        $res=$PayRecharge->where($where)->order('create_time desc')->paginate(['list_rows' => $limit, 'page' => $page], false)->each(function($item, $key){

            $status_text = ['待处理','通过','拒绝'];// 0待处理 1通过 2拒绝
            $item->status_text = $status_text[$item['status']];

        });
        return show($res);
    }

    /**
     * @Apidoc\Title("检测是否充值")
     * @Apidoc\Returned("data", type="array", desc="返回数据")
     */
    public function check_recharge()
    {
        return show();
        // $uid = session('home_user.id');
        // $user = $this->model->where('id', $uid)->find();
        // if ($user['product_class'] == 8) {
        //     return show();
        // }else{
        //     return show([], config('ToConfig.http_code.error'), '请充值500元解锁！');
        // }
    }

    /**
     * @Apidoc\Title("各种资金记录")
     * @Apidoc\Method("POST")
     * @Apidoc\Returned("data", type="bool", desc="返回成功失败结果")
     */
    public function money_records_by_type(){
        $uid= session('home_user.id');
        $page = $this->request->post('page', 1);//当前页
        $limit = $this->request->post('limit', 10);//每页显示数量
        $post = array_filter($this->request->post());//查询搜索条件

        $where=array();

        $where[]=array('uid','=',$uid);
        // 是否设置 资金类型
        if(isset($post['money_status']) && $post['money_status'] != '') {
            $where[]=array('status','in',$post['money_status']);
        }
        // 是否设置 货币类型
        if(isset($post['money_type']) && $post['money_type'] != '') {
            $where[]=array('money_type','=',$post['money_type']);
        }
        // 如果有时间
        if (isset($post['start']) && isset($post['end'])) {
            $where[]=array('create_time','>=',$post['start']);
            $where[]=array('create_time','<',$post['end']);
        }
        // 执行查询
        $PayWithdraw=new MoneyLog();
        $res=$PayWithdraw->field('*')->where($where)->order('create_time desc')->paginate(['list_rows' => $limit, 'page' => $page], false)->toArray();
        return show($res);
    }

    /**
     * @Apidoc\Title("可用余额 转账")
     * @Apidoc\Method("POST")
     * @Apidoc\Param("target_user_name", type="string",require=true, desc="目标人")
     * @Apidoc\Param("money", type="string",require=true, desc="钱数")
     * @Apidoc\Returned("data", type="array", desc="返回数据")
     */
    public function money_balance_transfer(){
        $uid= session('home_user.id');
        //过滤数据
        $postField = 'target_user_id,money,withdraw_pwd';
        $post   = $this->request->only(explode(',', $postField), 'post', null);
        // 判断产品是否 上架 并且正常的
        $user_self=$this->model->find($uid);
        $money = $post['money'];

        if((float)$post['money'] > $user_self['money_balance']){
            return show([],config('ToConfig.http_code.error'),'转账金额超过您持有金额');
        }

        // 检测密码pwdEncryption($post['pwd'])
        if(pwdEncryption($post['withdraw_pwd']) != $user_self['withdraw_pwd']){
            return show([],config('ToConfig.http_code.error'),'支付密码错误');
        }

        $mapTarget = [];
        $mapTarget['id'] = $post['target_user_id'];
        $user_target=$this->model->where($mapTarget)->find();
        if(empty($user_target['id'])){
            return show([],config('ToConfig.http_code.error'),'输入的用户名不正确');
        }

        $mapSelf = [];
        $mapSelf['id'] = $uid;
        $this->model->where($mapSelf)->dec('money_balance',$money)->update();
        $this->model->where($mapTarget)->inc('money_balance',$money)->update();

        // 日志记录
        MoneyLog::flowing(2,2,1,202,$user_self,$money,$uid,'转账 转出到'.$user_target['phone'],'money_balance');
        MoneyLog::flowing(1,1,1,111,$user_target,$money,$uid,$user_self['user_name'].'转账 转入','money_balance');

        return show([]);
    }

    /**
     * @Apidoc\Title("可提余额 转换")
     * @Apidoc\Method("POST")
     * @Apidoc\Param("money", type="string",require=true, desc="钱数")
     * @Apidoc\Returned("data", type="array", desc="返回数据")
     */
    public function money_gongfu_change(){
        $uid= session('home_user.id');
        //过滤数据
        $postField = 'money';
        $post   = $this->request->only(explode(',', $postField), 'post', null);
        // 判断产品是否 上架 并且正常的
        $user_self=$this->model->find($uid);
        $money = $post['money'];

        if((float)$post['money'] > $user_self['money_gongfu']){
            return show([],config('ToConfig.http_code.error'),'转账金额超过您持有金额');
        }

        $mapSelf = [];
        $mapSelf['id'] = $uid;
        $this->model->where($mapSelf)->dec('money_gongfu',$money)->update();
        $this->model->where($mapSelf)->inc('money_balance',$money)->update();

        // 日志记录
        MoneyLog::flowing(2,2,1,206,$user_self,$money,$uid,'余额转换 可提转出','money_gongfu');
        MoneyLog::flowing(1,1,1,109,$user_self,$money,$uid,'余额转换 可用转入','money_balance');

        return show([]);
    }

    /**
     * @Apidoc\Title("健康点转基金")
     * @Apidoc\Method("POST")
     * @Apidoc\Param("money", type="string",require=true, desc="转换数量")
     * @Apidoc\Returned("data", type="array", desc="返回数据")
     */
    public function point_to_fund(){
        $uid= session('home_user.id');
        //过滤数据
        $postField = 'money';
        $post   = $this->request->only(explode(',', $postField), 'post', null);
        // 判断产品是否 上架 并且正常的
        $user_self=$this->model->find($uid);
        $money = $post['money'];
        $zhuanhuan_rate = getSystemConfig('point_to_fund');
        if($zhuanhuan_rate > 0){
            $money_juanzeng = round($money/$zhuanhuan_rate,2);
        }else{
            return show([],config('ToConfig.http_code.error'),'转换设置不正确');
        }


        if((float)$post['money'] > $user_self['money_cishan']){
            return show([],config('ToConfig.http_code.error'),'数量不足');
        }

        $mapSelf = [];
        $mapSelf['id'] = $uid;
        $this->model->where($mapSelf)->dec('money_cishan',$money)->update();
        $this->model->where($mapSelf)->inc('money_juanzeng',$money_juanzeng)->update();

        // 日志记录
        MoneyLog::flowing(2,2,1,207,$user_self,$money,$uid,'健康点转基金 转出','money_cishan');
        MoneyLog::flowing(1,1,1,117,$user_self,$money_juanzeng,$uid,'健康点转基金 转入','money_juanzeng');

        return show([]);
    }

    /**
     * @Apidoc\Title("账变记录 可用金额记录")
     * @Apidoc\Method("POST")
     * @Apidoc\Param("money_type", type="string",require=true, desc="数据类型 money_balance money_gongfu money_cishan money_juanzeng ")
     * @Apidoc\Param("page", type="string",require=true, desc="页面")
     * @Apidoc\Param("limit", type="string",require=true, desc="分页限制")
     * @Apidoc\Param("start", type="string",require=true, desc="开始时间 可以不写")
     * @Apidoc\Param("end", type="string",require=true, desc="结束时间 可以不写")
     * @Apidoc\Returned("data", type="array", desc="返回数据")
     */
    public function money_change_records(){
        $uid= session('home_user.id');
        //过滤数据
        $postField = 'money_type,page,limit,start,end';
        $post   = $this->request->only(explode(',', $postField), 'post', null);

        $page = $this->request->post('page', 1);//当前页
        $limit = $this->request->post('limit', 10);//每页显示数量
        $start = $this->request->post('start'); // 搜索开始时间
        $end = $this->request->post('end'); // 搜索结束时间
        $date = [];
        if(!empty($start) && !empty($end)){
            $date['start'] = $start;
            $date['end'] = $end;
        }

        $map = [];
        $map['uid']= $uid;
        $map['money_type']= $post['money_type'];
        $res=(new MoneyLog())->page_list($map,$limit,$page,'id desc',$date);
        return show($res);
    }

    /**
     * @Apidoc\Title("下级购买 返佣记录")
     * @Apidoc\Method("POST")
     * @Apidoc\Param("page", type="string",require=true, desc="页面")
     * @Apidoc\Param("limit", type="string",require=true, desc="分页限制")
     * @Apidoc\Param("start", type="string",require=true, desc="开始时间 可以不写")
     * @Apidoc\Param("end", type="string",require=true, desc="结束时间 可以不写")
     * @Apidoc\Returned("data", type="array", desc="返回数据")
     */
    public function fanyong_records(){
        $uid= session('home_user.id');
        //过滤数据
        // $postField = 'page,limit,start,end';
        // $post   = $this->request->only(explode(',', $postField), 'post', null);

        $page = $this->request->post('page', 1);//当前页
        $limit = $this->request->post('limit', 10);//每页显示数量
        $start = $this->request->post('start'); // 搜索开始时间
        $end = $this->request->post('end'); // 搜索结束时间
        $date = [];
        if(!empty($start) && !empty($end)){
            $date['start'] = $start;
            $date['end'] = $end;
        }

        $map = [];
        $map['user_id']= $uid;
        $res=(new TouziFanyongLog())->page_list($map,$limit,$page,$date);
        return show($res);
    }

    /**
     * @Apidoc\Title("提现开启状态")
     * @Apidoc\Method("GET")
     * @Apidoc\Returned("data", type="array", desc="返回数据")
     */
    public function withdraw_status() {
        $res = SysConfig::field('name,value,mark')
            ->whereIn('name', 'money_balance_status,money_gongfu_status,money_cishan_status')
            ->select()->toArray();
        return show($res);
    }
// 类结束了
}
